package com.gitee.chessboard.model.dictionary;

import com.gitee.chessboard.enums.DictionaryType;
import com.gitee.chessboard.jdbc.parser.annotations.Id;
import com.gitee.chessboard.manager.DictionaryManager;
import com.gitee.chessboard.model.word.Word;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * 字典的抽象实现
 *
 * @author 敲代码的旺财
 * @date 2021/11/17 17:28
 */
public abstract class AbstractDictionary implements Dictionary {
    /**
     * 字典管理器
     */
    private DictionaryManager dictionaryManager;

    /**
     * 字典名称
     */
    private String dictionaryName;
    /**
     * 字典编码
     */
    @Id
    private String dictionaryCode;
    /**
     * 字典类型
     */
    private DictionaryType dictionaryType;
    /**
     * 当前字典下的所有词
     */
    private List<Word> words;

    /**
     * 当前字典下的所有词,用于根据词编码查找
     */
    private Map<String, Word> wordCodeSearch;

    public AbstractDictionary() {
        this(null);
    }

    public AbstractDictionary(DictionaryManager dictionaryManager) {
        this(new ArrayList<>(), dictionaryManager);
    }

    public AbstractDictionary(List<Word> words, DictionaryManager dictionaryManager) {
        this.dictionaryManager = dictionaryManager;
        this.words = words;
        this.wordCodeSearch = new ConcurrentHashMap<>();
        refreshSearch();
    }

    /**
     * 用于刷新搜索缓存
     */
    void refreshSearch() {
        this.wordCodeSearch = this.words.stream().collect(Collectors.toMap(Word::getWordCode, m -> m));
    }

    /**
     * 获取字典名称
     *
     * @return 字典名称
     */
    @Override
    public String getDictionaryName() {
        return dictionaryName;
    }

    /**
     * 获取字典编码
     *
     * @return 字典编码
     */
    @Override
    public String getDictionaryCode() {
        return dictionaryCode;
    }

    /**
     * 获取字典类型
     *
     * @return 字典类型
     */
    @Override
    public DictionaryType getDictionaryType() {
        return dictionaryType;
    }

    /**
     * 设置字典名称
     *
     * @param dictionaryName 字典名称
     */
    @Override
    public void setDictionaryName(String dictionaryName) {
        this.dictionaryName = dictionaryName;
    }

    /**
     * 设置字典类型
     *
     * @param dictionaryCode 字典类型
     */
    @Override
    public void setDictionaryCode(String dictionaryCode) {
        this.dictionaryCode = dictionaryCode;
    }

    /**
     * 设置字典类型
     *
     * @param dictionaryType 字典类型
     */
    @Override
    public void setDictionaryType(DictionaryType dictionaryType) {
        this.dictionaryType = dictionaryType;
    }

    /**
     * 获取所有词
     *
     * @return 词集合
     */
    @Override
    public List<Word> get() {
        return words;
    }

    /**
     * 获取词
     *
     * @param wordCode 词编码
     * @return 词实例
     */
    @Override
    public Word get(String wordCode) {
        return wordCodeSearch.get(wordCode);
    }

    /**
     * 添加词
     *
     * @param word 词
     */
    @Override
    public void add(Word word) {
        Word oldWord = wordCodeSearch.get(word.getWordCode());
        if (oldWord != null) {
            throw new IllegalArgumentException("同一个字典中，无法添加编码重复的词");
        }
        words.add(word);
        refreshSearch();
    }

    /**
     * 删除词
     *
     * @param wordCode 词的编码
     */
    @Override
    public void del(String wordCode) {
        Word word = wordCodeSearch.get(wordCode);
        words.remove(word);
        refreshSearch();
    }

    /**
     * 删除词
     *
     * @param word 词
     */
    @Override
    public void del(Word word) {
        words.remove(word);
        refreshSearch();
    }

    /**
     * 保存当前字典
     */
    @Override
    public void saveSelf() {
        dictionaryManager.save(this);
    }

    /**
     * 删除当前字典
     */
    @Override
    public void delSelf() {
        dictionaryManager.del(this);
    }

    /**
     * 设置字典管理器
     *
     * @param dictionaryManager 字典管理器
     */
    @Override
    public void setDictionaryManager(DictionaryManager dictionaryManager) {
        this.dictionaryManager = dictionaryManager;
    }

    @Override
    public String toString() {
        return dictionaryName;
    }
}
